`include "common.svh"
`define COMPACT_ISSUE_QUEUE_DIFFTEST
`ifdef COMPACT_ISSUE_QUEUE_DIFFTEST
import "DPI-C" function int ciq_create(
  int id,
  string name,
  int size,
  bit inorder
);
import "DPI-C" function void ciq_wake(
  int id,
  int prf_idx,
  longint prf_data
);
import "DPI-C" function void ciq_early_wake(
  int id,
  int prf_idx
);
import "DPI-C" function void ciq_enq(
  int id,
  int rob_idx,
  int prs1,
  int prs2,
  longint src1,
  longint src2,
  bit src1_valid,
  bit src2_valid,
  bit src1_wakeup,
  bit src2_wakeup
);

import "DPI-C" function void ciq_deq(
  int id,
  int rob_idx,
  int prs1,
  int prs2,
  longint src1,
  longint src2,
  bit src1_valid,
  bit src2_valid,
  bit src1_wakeup,
  bit src2_wakeup
);

`endif
module compress_issue_queue #(
    parameter RF_WRITE_WIDTH = 5,
    parameter WAKEUP_WIDTH = 3,  //early wake up
    parameter ENQ_WIDTH = 4,
    parameter DEQ_WIDTH = 2,
    parameter SIZE = 16,
    parameter INORDER = 0,
    localparam AW = $clog2(SIZE)
) (
    input clk,
    input rst,
    //Redirect
    // input i_redirect_valid,
    // input ROB_PTR i_redirect_rob_idx,
    //from regfile write port
    input i_write_valid[RF_WRITE_WIDTH-1:0],
    input PRF_IDX i_write_prf_idx[RF_WRITE_WIDTH-1:0],
    input word_t i_write_prf_data[RF_WRITE_WIDTH-1:0],
    //early wake-up port
    input i_wakeup_valid[WAKEUP_WIDTH-1:0],
    input PRF_IDX i_wakeup_prf_idx[WAKEUP_WIDTH-1:0],
    //from dispatch
    input i_valid[ENQ_WIDTH-1:0],
    input ISSUE_OP i_iop[ENQ_WIDTH-1:0],
    output i_ready,
    //to exu
    output o_valid[DEQ_WIDTH-1:0],
    output ISSUE_OP o_iop[DEQ_WIDTH-1:0],
    input o_ready,
    //to rob
    output o_rob_issue_valid[DEQ_WIDTH-1:0],
    output ROB_PTR o_rob_issue_rob_idx[DEQ_WIDTH-1:0]
);

  logic [ENQ_WIDTH-1:0] i_fire;
  logic [DEQ_WIDTH-1:0] o_fire;
  logic [AW:0] enq_ptr, enq_num, deq_num,  /*redirect_enq_ptr,*/ enq_ptr_next;
  assign i_ready = enq_ptr <= (SIZE - ENQ_WIDTH);
  assign enq_ptr_next = enq_ptr + enq_num - deq_num;
  always_comb begin
    integer i;
    enq_num = 'b0;
    for (i = 0; i < ENQ_WIDTH; i = i + 1) begin
      i_fire[i] = i_valid[i] & i_ready;
      if (i_fire[i]) enq_num = enq_num + 'b1;
    end
    deq_num = 'b0;
    for (i = 0; i < DEQ_WIDTH; i = i + 1) begin
      o_fire[i] = o_valid[i] & o_ready;
      if (o_fire[i]) deq_num = deq_num + 'b1;
    end
  end
  reg_r #(AW + 1) enq_ptr_r (
      //   .load((|i_fire) | i_redirect_valid),
      // .din (i_redirect_valid ? redirect_enq_ptr : enq_ptr_next),
      .din (enq_ptr_next),
      .dout(enq_ptr),
      .*
  );

  ISSUE_OP q_rentry[SIZE-1:0]  /* verilator public */;
  ISSUE_OP q_entry_next[SIZE-1:0]  /* verilator public */;
  logic q_ready[SIZE-1:0]  /* verilator public */;
  logic q_deq[SIZE-1:0]  /* verilator public */;

  logic [AW-1:0] o_iop_ptr[DEQ_WIDTH-1:0];
  logic [AW:0] valid_entry;
  always_comb begin
    integer i;
    valid_entry = 'b0;
    for (i = 0; i < SIZE; i = i + 1) begin
      if (q_ready[i]) begin
        valid_entry = valid_entry + 'b1;
      end
    end
  end
  function logic [AW-1:0] PriorIdxFinder;
    input [AW-1:0] idx;
    if (INORDER) begin
      return idx;
    end else begin
      logic [AW:0] valid_cnt;
      logic [AW-1:0] out;
      integer i;
      out = 'b0;
      valid_cnt = 'b0;
      for (i = 0; i < SIZE; i = i + 1) begin
        if (q_ready[i]) begin
          if (valid_cnt == {1'b0, idx}) begin
            out = i[AW-1:0];
          end
          valid_cnt = valid_cnt + 'b1;
        end
      end
      return out;
    end
  endfunction

  logic [$clog2(DEQ_WIDTH):0] compress_num[SIZE-1:0];
  always_comb begin
    integer i;
    compress_num[0] = q_deq[0] ? 'b1 : 'b0;
    for (i = 1; i < SIZE; i = i + 1) begin
      if (q_deq[i]) begin
        compress_num[i] = compress_num[i-1] + 'b1;
      end else begin
        compress_num[i] = compress_num[i-1];
      end
    end
  end

  function logic [AW-1:0] CompressPriorIdxFinder;
    input [AW-1:0] idx;
    logic [AW-1:0] out;
    logic [$clog2(DEQ_WIDTH):0] valid_cnt, offset;
    integer i;
    begin
      out = compress_num[idx] == 0 ? 'b0 : DEQ_WIDTH;
      valid_cnt = 'b0;
      offset = 'b0;
      i = 'b0;
      i[AW-1:0] = idx + 'b1;
      for (; (i < SIZE) & (offset < DEQ_WIDTH); i = i + 1) begin
        offset = offset + 'b1;
        if (!q_deq[i]) begin
          valid_cnt = valid_cnt + 'b1;
          if (valid_cnt == compress_num[idx]) begin
            out[$clog2(DEQ_WIDTH):0] = offset;
          end
        end
      end
    end
    return out + idx;
  endfunction

  genvar gi;
  generate
    // localparam ROP_SIZE = $size(RenamedOP);
    localparam ENQ_AW = $clog2(ENQ_WIDTH);
    // localparam ROB_PTR_SIZE = $size(ROB_PTR);
    localparam ISSUE_OP_SIZE = $size(ISSUE_OP);

    ISSUE_OP enq_op[ENQ_WIDTH-1:0];
    logic capture_op_valid[ENQ_WIDTH-1:0];
    ISSUE_OP capture_op[ENQ_WIDTH-1:0];
    ISSUE_OP iop[ENQ_WIDTH-1:0];
    for (gi = 0; gi < ENQ_WIDTH; gi = gi + 1) begin : CaptureEnqSrc
      assign iop[gi] = capture_op_valid[gi] ? capture_op[gi] : i_iop[gi];
      reg_r #(1) capture_op_valid_r (
          .din (i_valid[gi]),
          .dout(capture_op_valid[gi]),
          .rst (rst | i_ready),
          .*
      );
      reg_l #(ISSUE_OP_SIZE) capture_op_r (
          .load(i_valid[gi]),
          .din (enq_op[gi]),
          .dout(capture_op[gi]),
          .*
      );
      logic [WAKEUP_WIDTH-1:0] wakeup_enq_op_src1_sel, wakeup_enq_op_src2_sel;
      assign enq_op[gi].src1_wakeup = (|wakeup_enq_op_src1_sel) & (~iop[gi].src1_valid) | iop[gi].src1_wakeup;
      assign enq_op[gi].src2_wakeup = (|wakeup_enq_op_src2_sel) & (~iop[gi].src2_valid) | iop[gi].src2_wakeup;
      assign enq_op[gi].rop = iop[gi].rop;
      assign enq_op[gi].rob_idx = iop[gi].rob_idx;
      logic [RF_WRITE_WIDTH-1:0] capture_enq_op_src1_sel, capture_enq_op_src2_sel;
      word_t capture_enq_op_src1, capture_enq_op_src2;
      assign enq_op[gi].src1_valid = (|capture_enq_op_src1_sel) | iop[gi].src1_valid;
      assign enq_op[gi].src2_valid = (|capture_enq_op_src2_sel) | iop[gi].src2_valid;
      assign enq_op[gi].src1 = iop[gi].src1_valid ? iop[gi].src1 : capture_enq_op_src1;
      assign enq_op[gi].src2 = iop[gi].src2_valid ? iop[gi].src2 : capture_enq_op_src2;

      always_comb begin
        integer i;
        for (i = 0; i < RF_WRITE_WIDTH; i = i + 1) begin
          capture_enq_op_src1_sel[i] = i_write_valid[i] & (i_write_prf_idx[i] == iop[gi].rop.prs1);
          capture_enq_op_src2_sel[i] = i_write_valid[i] & (i_write_prf_idx[i] == iop[gi].rop.prs2);
        end
        for (i = 0; i < WAKEUP_WIDTH; i = i + 1) begin
          wakeup_enq_op_src1_sel[i] = i_wakeup_valid[i] & (i_wakeup_prf_idx[i] == iop[gi].rop.prs1);
          wakeup_enq_op_src2_sel[i] = i_wakeup_valid[i] & (i_wakeup_prf_idx[i] == iop[gi].rop.prs2);
        end
      end
      MUX_OH #(RF_WRITE_WIDTH, `WORD_BITS, 0) mux_capture_enq_op_src1 (
          .sel (capture_enq_op_src1_sel),
          .din (i_write_prf_data),
          .dout(capture_enq_op_src1)
      );
      MUX_OH #(RF_WRITE_WIDTH, `WORD_BITS, 0) mux_capture_enq_op_src2 (
          .sel (capture_enq_op_src2_sel),
          .din (i_write_prf_data),
          .dout(capture_enq_op_src2)
      );
    end
    logic [AW-1:0] compress_idx[SIZE-1:0];
    logic wsel[SIZE-1:0];
    logic wvalid[SIZE-1:0];
    for (gi = 0; gi < SIZE; gi = gi + 1) begin : QueueEntry
      assign compress_idx[gi] = CompressPriorIdxFinder(gi);
      wire entry_valid = enq_ptr > gi;
      wire [AW:0] enq_ptr_distance = gi - enq_ptr;
      wire [ENQ_AW-1:0] widx = enq_ptr_distance[ENQ_AW-1:0];
      assign wsel[gi]   = (!entry_valid) & (enq_ptr_distance < ENQ_WIDTH);
      assign wvalid[gi] = i_valid[widx];
      wire we = wsel[gi] & wvalid[gi];

      ISSUE_OP wop;
      assign wop = enq_op[widx];
      assign q_ready[gi] = entry_valid & (q_rentry[gi].src1_valid|q_rentry[gi].src1_wakeup) &( q_rentry[gi].src2_valid| q_rentry[gi].src2_wakeup);
      //Capture op src

      logic [WAKEUP_WIDTH-1:0] wakeup_enq_op_src1_sel, wakeup_enq_op_src2_sel;

      logic capture_src1_valid, capture_src2_valid;
      word_t capture_src1, capture_src2;
      wire need_capture_src1 = entry_valid & (!q_rentry[gi].src1_valid);
      wire need_capture_src2 = entry_valid & (!q_rentry[gi].src2_valid);
      PRF_IDX capture_prs1, capture_prs2;
      assign capture_prs1 = q_rentry[gi].rop.prs1;
      assign capture_prs2 = q_rentry[gi].rop.prs2;
      logic [RF_WRITE_WIDTH-1:0] capture_src1_sel, capture_src2_sel;
      assign capture_src1_valid = (|capture_src1_sel) & need_capture_src1;
      assign capture_src2_valid = (|capture_src2_sel) & need_capture_src2;
      always_comb begin
        integer i;
        for (i = 0; i < RF_WRITE_WIDTH; i = i + 1) begin
          capture_src1_sel[i] = i_write_valid[i] & (i_write_prf_idx[i] == capture_prs1);
          capture_src2_sel[i] = i_write_valid[i] & (i_write_prf_idx[i] == capture_prs2);
        end
        for (i = 0; i < WAKEUP_WIDTH; i = i + 1) begin
          wakeup_enq_op_src1_sel[i] = i_wakeup_valid[i] & (i_wakeup_prf_idx[i] == capture_prs1);
          wakeup_enq_op_src2_sel[i] = i_wakeup_valid[i] & (i_wakeup_prf_idx[i] == capture_prs2);
        end
      end
      MUX_OH #(RF_WRITE_WIDTH, `WORD_BITS, 0) mux_capture_src1 (
          .sel (capture_src1_sel),
          .din (i_write_prf_data),
          .dout(capture_src1)
      );
      MUX_OH #(RF_WRITE_WIDTH, `WORD_BITS, 0) mux_capture_src2 (
          .sel (capture_src2_sel),
          .din (i_write_prf_data),
          .dout(capture_src2)
      );

      assign q_entry_next[gi].src1_wakeup = (we ? wop.src1_wakeup :((|wakeup_enq_op_src1_sel)&(~q_rentry[gi].src1_valid)) |  q_rentry[gi].src1_wakeup);
      assign q_entry_next[gi].src2_wakeup = (we ? wop.src2_wakeup :((|wakeup_enq_op_src2_sel)&(~q_rentry[gi].src2_valid)) |  q_rentry[gi].src2_wakeup);
      assign q_entry_next[gi].rop = we ? wop.rop : q_rentry[gi].rop;
      assign q_entry_next[gi].rob_idx = we ? wop.rob_idx : q_rentry[gi].rob_idx;
      assign q_entry_next[gi].src1 = capture_src1_valid ? capture_src1 : we ? wop.src1 : q_rentry[gi].src1;
      assign q_entry_next[gi].src2 = capture_src2_valid ? capture_src2 : we ? wop.src2 : q_rentry[gi].src2;
      assign q_entry_next[gi].src1_valid =  capture_src1_valid | (we ? wop.src1_valid : q_rentry[gi].src1_valid);
      assign q_entry_next[gi].src2_valid =  capture_src2_valid | (we ? wop.src2_valid : q_rentry[gi].src2_valid);

      reg_next #(ISSUE_OP_SIZE) issueq_entry_r (
          .din (q_entry_next[compress_idx[gi]]),
          .dout(q_rentry[gi]),
          .*
      );
    end

    //Select the oldest instruction
    logic [AW-1:0] o_iop_ptr_next[DEQ_WIDTH-1:0];
    for (gi = 0; gi < DEQ_WIDTH; gi = gi + 1) begin : DeqLogic
      assign o_iop_ptr_next[gi] = PriorIdxFinder(gi);
      ISSUE_OP o_iop_next;
      assign o_iop_next = q_rentry[o_iop_ptr_next[gi]];
      wire o_valid_next = q_ready[o_iop_ptr_next[gi]] & (valid_entry > gi);
      assign o_valid[gi] = o_valid_next;
      assign o_iop[gi] = o_iop_next;
      assign o_iop_ptr[gi] = o_iop_ptr_next[gi];
      assign o_rob_issue_valid[gi] = o_valid[gi] & o_ready;
      assign o_rob_issue_rob_idx[gi] = o_iop[gi].rob_idx;
    end
    always_comb begin
      integer i;
      for (i = 0; i < SIZE; i = i + 1) begin
        q_deq[i] = 'b0;
      end
      for (i = 0; i < DEQ_WIDTH; i = i + 1) begin
        q_deq[o_iop_ptr[i]] = q_deq[o_iop_ptr[i]] | (o_valid[i] & o_ready);
      end
    end
  endgenerate
`ifdef COMPACT_ISSUE_QUEUE_DIFFTEST
  `define ZEXT(width, val) {{(width-$size(val)){1'b0}},val}
  int id = 0;
  always_ff @(posedge clk) begin
    integer i;
    if (rst) begin
      id <= ciq_create(id, $sformatf("%m"), SIZE, INORDER);
    end else begin
      if (o_ready) begin
        for (i = 0; i < DEQ_WIDTH; i = i + 1) begin
          if (o_valid[i])
            ciq_deq(
            id,
            `ZEXT(32, o_iop[i].rob_idx),
            `ZEXT(32, o_iop[i].rop.prs1),
                    `ZEXT(32, o_iop[i].rop.prs2), o_iop[i].src1, o_iop[i].src2, o_iop[i].src1_valid,
                    o_iop[i].src2_valid, o_iop[i].src1_wakeup, o_iop[i].src2_wakeup);
        end
      end
      if (i_ready) begin
        for (i = 0; i < ENQ_WIDTH; i = i + 1) begin
          if (i_valid[i])
            ciq_enq(
            id,
            `ZEXT(32, enq_op[i].rob_idx),
            `ZEXT(32, enq_op[i].rop.prs1),
                    `ZEXT(32, enq_op[i].rop.prs2), enq_op[i].src1, enq_op[i].src2,
                    enq_op[i].src1_valid, enq_op[i].src2_valid, enq_op[i].src1_wakeup,
                    enq_op[i].src2_wakeup);
        end
      end

      for (i = 0; i < RF_WRITE_WIDTH; i = i + 1) begin
        if (i_write_valid[i]) begin
          ciq_wake(
          id,
          `ZEXT(32, i_write_prf_idx[i]),
          i_write_prf_data[i]);
        end
      end
      for (i = 0; i < WAKEUP_WIDTH; i = i + 1) begin
        if (i_wakeup_valid[i]) begin
          ciq_early_wake(
          id,
          `ZEXT(32, i_wakeup_prf_idx[i]));
        end
      end
    end

  end
`endif
endmodule

module issue #(
    parameter DISPATCH_WIDTH = 2,
    parameter RF_WRITE_WIDTH = 5,
    parameter WAKEUP_WIDTH = 3,  //early wake up
    parameter ALU_NUM = 2,
    parameter BRU_NUM = 1,
    parameter LSU_NUM = 1,
    parameter MDU_NUM = 1,
    parameter MISC_NUM = 1,
    parameter ALU_IQ_SIZE = 16,
    parameter BRU_IQ_SIZE = 8,
    parameter LSU_IQ_SIZE = 8,
    parameter MDU_IQ_SIZE = 8,
    parameter MISC_IQ_SIZE = 4,
    parameter ISSUE_WIDTH = ALU_NUM + BRU_NUM + LSU_NUM + MDU_NUM + MISC_NUM
) (
    input clk,
    input rst,
    //Regfile Write Port
    input i_write_valid[RF_WRITE_WIDTH-1:0],
    input PRF_IDX i_write_prf_idx[RF_WRITE_WIDTH-1:0],
    input word_t i_write_prf_data[RF_WRITE_WIDTH-1:0],
    //early wake-up port
    input i_wakeup_valid[WAKEUP_WIDTH-1:0],
    input PRF_IDX i_wakeup_prf_idx[WAKEUP_WIDTH-1:0],
    //From Dispatch
    input i_alu_valid[DISPATCH_WIDTH-1:0],
    input ISSUE_OP i_alu_iop[DISPATCH_WIDTH-1:0],
    output i_alu_ready,
    input i_bru_valid[DISPATCH_WIDTH-1:0],
    input ISSUE_OP i_bru_iop[DISPATCH_WIDTH-1:0],
    output i_bru_ready,
    input i_lsu_valid[DISPATCH_WIDTH-1:0],
    input ISSUE_OP i_lsu_iop[DISPATCH_WIDTH-1:0],
    output i_lsu_ready,
    input i_mdu_valid[DISPATCH_WIDTH-1:0],
    input ISSUE_OP i_mdu_iop[DISPATCH_WIDTH-1:0],
    output i_mdu_ready,
    input i_misc_valid[DISPATCH_WIDTH-1:0],
    input ISSUE_OP i_misc_iop[DISPATCH_WIDTH-1:0],
    output i_misc_ready,
    //To Fu
    output o_alu_valid[ALU_NUM-1:0],
    output ISSUE_OP o_alu_iop[ALU_NUM-1:0],
    input o_alu_ready,
    output o_bru_valid[BRU_NUM-1:0],
    output ISSUE_OP o_bru_iop[BRU_NUM-1:0],
    input o_bru_ready,
    output o_lsu_valid[LSU_NUM-1:0],
    output ISSUE_OP o_lsu_iop[LSU_NUM-1:0],
    input o_lsu_ready,
    output o_mdu_valid[MDU_NUM-1:0],
    output ISSUE_OP o_mdu_iop[MDU_NUM-1:0],
    input o_mdu_ready,
    output o_misc_valid[MISC_NUM-1:0],
    output ISSUE_OP o_misc_iop[MISC_NUM-1:0],
    input o_misc_ready,

    output o_rob_issue_valid[ISSUE_WIDTH-1:0],
    output ROB_PTR o_rob_issue_rob_idx[ISSUE_WIDTH-1:0],
    output o_rob_replay_valid[ISSUE_WIDTH-1:0],
    output ROB_PTR o_rob_replay_rob_idx[ISSUE_WIDTH-1:0]
);

  logic bypass_i_alu_valid[ALU_NUM-1:0];
  ISSUE_OP bypass_i_alu_iop[ALU_NUM-1:0];
  logic bypass_i_alu_ready;
  logic bypass_i_bru_valid[BRU_NUM-1:0];
  ISSUE_OP bypass_i_bru_iop[BRU_NUM-1:0];
  logic bypass_i_bru_ready;
  logic bypass_i_lsu_valid[LSU_NUM-1:0];
  ISSUE_OP bypass_i_lsu_iop[LSU_NUM-1:0];
  logic bypass_i_lsu_ready;
  logic bypass_i_mdu_valid[MDU_NUM-1:0];
  ISSUE_OP bypass_i_mdu_iop[MDU_NUM-1:0];
  logic bypass_i_mdu_ready;
  logic bypass_i_misc_valid[MISC_NUM-1:0];
  ISSUE_OP bypass_i_misc_iop[MISC_NUM-1:0];
  logic bypass_i_misc_ready;

  logic bypass_o_alu_rob_replay_valid[ALU_NUM-1:0];
  ROB_PTR bypass_o_alu_rob_replay_rob_idx[ALU_NUM-1:0];
  logic bypass_o_bru_rob_replay_valid[BRU_NUM-1:0];
  ROB_PTR bypass_o_bru_rob_replay_rob_idx[BRU_NUM-1:0];
  logic bypass_o_lsu_rob_replay_valid[LSU_NUM-1:0];
  ROB_PTR bypass_o_lsu_rob_replay_rob_idx[LSU_NUM-1:0];
  logic bypass_o_mdu_rob_replay_valid[MDU_NUM-1:0];
  ROB_PTR bypass_o_mdu_rob_replay_rob_idx[MDU_NUM-1:0];
  logic bypass_o_misc_rob_replay_valid[MISC_NUM-1:0];
  ROB_PTR bypass_o_misc_rob_replay_rob_idx[MISC_NUM-1:0];

  assign o_rob_replay_valid = {
    bypass_o_alu_rob_replay_valid,
    bypass_o_bru_rob_replay_valid,
    bypass_o_lsu_rob_replay_valid,
    bypass_o_mdu_rob_replay_valid,
    bypass_o_misc_rob_replay_valid
  };
  assign o_rob_replay_rob_idx = {
    bypass_o_alu_rob_replay_rob_idx,
    bypass_o_bru_rob_replay_rob_idx,
    bypass_o_lsu_rob_replay_rob_idx,
    bypass_o_mdu_rob_replay_rob_idx,
    bypass_o_misc_rob_replay_rob_idx
  };

  logic o_alu_issue_valid[ALU_NUM-1:0];
  ROB_PTR o_alu_issue_rob_idx[ALU_NUM-1:0];
  logic o_bru_issue_valid[BRU_NUM-1:0];
  ROB_PTR o_bru_issue_rob_idx[BRU_NUM-1:0];
  logic o_lsu_issue_valid[LSU_NUM-1:0];
  ROB_PTR o_lsu_issue_rob_idx[LSU_NUM-1:0];
  logic o_mdu_issue_valid[MDU_NUM-1:0];
  ROB_PTR o_mdu_issue_rob_idx[MDU_NUM-1:0];
  logic o_misc_issue_valid[MISC_NUM-1:0];
  ROB_PTR o_misc_issue_rob_idx[MISC_NUM-1:0];

  assign o_rob_issue_valid = {
    o_alu_issue_valid, o_bru_issue_valid, o_lsu_issue_valid, o_mdu_issue_valid, o_misc_issue_valid
  };

  assign o_rob_issue_rob_idx = {
    o_alu_issue_rob_idx,
    o_bru_issue_rob_idx,
    o_lsu_issue_rob_idx,
    o_mdu_issue_rob_idx,
    o_misc_issue_rob_idx
  };

  bypass #(RF_WRITE_WIDTH, ALU_NUM) inst_bypass_alu (
      .i_valid(bypass_i_alu_valid),
      .i_iop(bypass_i_alu_iop),
      .i_ready(bypass_i_alu_ready),
      .o_valid(o_alu_valid),
      .o_iop(o_alu_iop),
      .o_ready(o_alu_ready),
      .o_rob_replay_valid(bypass_o_alu_rob_replay_valid),
      .o_rob_replay_rob_idx(bypass_o_alu_rob_replay_rob_idx),
      .*
  );
  compress_issue_queue #(RF_WRITE_WIDTH, WAKEUP_WIDTH, DISPATCH_WIDTH, ALU_NUM, ALU_IQ_SIZE) ciq_alu (
      .i_valid(i_alu_valid),
      .i_iop(i_alu_iop),
      .i_ready(i_alu_ready),
      .o_valid(bypass_i_alu_valid),
      .o_iop(bypass_i_alu_iop),
      .o_ready(bypass_i_alu_ready),
      .o_rob_issue_valid(o_alu_issue_valid),
      .o_rob_issue_rob_idx(o_alu_issue_rob_idx),
      .*
  );
  bypass #(RF_WRITE_WIDTH, BRU_NUM) inst_bypass_bru (
      .i_valid(bypass_i_bru_valid),
      .i_iop(bypass_i_bru_iop),
      .i_ready(bypass_i_bru_ready),
      .o_valid(o_bru_valid),
      .o_iop(o_bru_iop),
      .o_ready(o_bru_ready),
      .o_rob_replay_valid(bypass_o_bru_rob_replay_valid),
      .o_rob_replay_rob_idx(bypass_o_bru_rob_replay_rob_idx),
      .*
  );
  compress_issue_queue #(RF_WRITE_WIDTH, WAKEUP_WIDTH, DISPATCH_WIDTH, BRU_NUM, BRU_IQ_SIZE) ciq_bru (
      .i_valid(i_bru_valid),
      .i_iop(i_bru_iop),
      .i_ready(i_bru_ready),
      .o_valid(bypass_i_bru_valid),
      .o_iop(bypass_i_bru_iop),
      .o_ready(bypass_i_bru_ready),
      .o_rob_issue_valid(o_bru_issue_valid),
      .o_rob_issue_rob_idx(o_bru_issue_rob_idx),
      .*
  );
  bypass #(RF_WRITE_WIDTH, LSU_NUM) inst_bypass_lsu (
      .i_valid(bypass_i_lsu_valid),
      .i_iop(bypass_i_lsu_iop),
      .i_ready(bypass_i_lsu_ready),
      .o_valid(o_lsu_valid),
      .o_iop(o_lsu_iop),
      .o_ready(o_lsu_ready),
      .o_rob_replay_valid(bypass_o_lsu_rob_replay_valid),
      .o_rob_replay_rob_idx(bypass_o_lsu_rob_replay_rob_idx),
      .*
  );
  //Force LSU issue queue inorder
  compress_issue_queue #(RF_WRITE_WIDTH, WAKEUP_WIDTH, DISPATCH_WIDTH, LSU_NUM, LSU_IQ_SIZE, 1) ciq_lsu (
      .i_valid(i_lsu_valid),
      .i_iop(i_lsu_iop),
      .i_ready(i_lsu_ready),
      .o_valid(bypass_i_lsu_valid),
      .o_iop(bypass_i_lsu_iop),
      .o_ready(bypass_i_lsu_ready),
      .o_rob_issue_valid(o_lsu_issue_valid),
      .o_rob_issue_rob_idx(o_lsu_issue_rob_idx),
      .*
  );
  bypass #(RF_WRITE_WIDTH, MDU_NUM) inst_bypass_mdu (
      .i_valid(bypass_i_mdu_valid),
      .i_iop(bypass_i_mdu_iop),
      .i_ready(bypass_i_mdu_ready),
      .o_valid(o_mdu_valid),
      .o_iop(o_mdu_iop),
      .o_ready(o_mdu_ready),
      .o_rob_replay_valid(bypass_o_mdu_rob_replay_valid),
      .o_rob_replay_rob_idx(bypass_o_mdu_rob_replay_rob_idx),
      .*
  );
  compress_issue_queue #(RF_WRITE_WIDTH, WAKEUP_WIDTH, DISPATCH_WIDTH, MDU_NUM, MDU_IQ_SIZE) ciq_mdu (
      .i_valid(i_mdu_valid),
      .i_iop(i_mdu_iop),
      .i_ready(i_mdu_ready),
      .o_valid(bypass_i_mdu_valid),
      .o_iop(bypass_i_mdu_iop),
      .o_ready(bypass_i_mdu_ready),
      .o_rob_issue_valid(o_mdu_issue_valid),
      .o_rob_issue_rob_idx(o_mdu_issue_rob_idx),
      .*
  );
  bypass #(RF_WRITE_WIDTH, MISC_NUM) inst_bypass_misc (
      .i_valid(bypass_i_misc_valid),
      .i_iop(bypass_i_misc_iop),
      .i_ready(bypass_i_misc_ready),
      .o_valid(o_misc_valid),
      .o_iop(o_misc_iop),
      .o_ready(o_misc_ready),
      .o_rob_replay_valid(bypass_o_misc_rob_replay_valid),
      .o_rob_replay_rob_idx(bypass_o_misc_rob_replay_rob_idx),
      .*
  );
  //Force MISC issue queue inorder
  compress_issue_queue #(RF_WRITE_WIDTH, WAKEUP_WIDTH, DISPATCH_WIDTH, MISC_NUM, MISC_IQ_SIZE, 1) ciq_misc (
      .i_valid(i_misc_valid),
      .i_iop(i_misc_iop),
      .i_ready(i_misc_ready),
      .o_valid(bypass_i_misc_valid),
      .o_iop(bypass_i_misc_iop),
      .o_ready(bypass_i_misc_ready),
      .o_rob_issue_valid(o_misc_issue_valid),
      .o_rob_issue_rob_idx(o_misc_issue_rob_idx),
      .*
  );

endmodule
